#pragma once
#include "stdafx.h"
#include "IStackAllocator.h"


template <class T>
class StackAllocator : public IStackAllocator
{

	unsigned short SIZE;
	T **stack;
	unsigned short stackPointer;
	T* pool;

	unsigned short freeObject;
	unsigned short maxObject;



public:

	virtual T* pop()
	{
		//assert(stackPointer>=0, "Error: Stack pointer is negative");
		if(stackPointer<=0)
		{
			Ogre::LogManager::getSingletonPtr()->logMessage(Ogre::LML_CRITICAL,"Not enough space in pool allocator with size "+Ogre::StringConverter::toString(SIZE));
		}

		if(stackPointer==0)
		{
			return 0;
		}

		--freeObject;

		return stack[--stackPointer];
	}

	virtual void push(T* object)
	{
		//assert(stackPointer>=0, "Error: Stack pointer is negative");
		//assert(stackPointer!=maxObject, "Error,Some objects freed more than once");

		++freeObject;
		stack[stackPointer++] = object;
	}

	virtual unsigned short getFreeObjectCount()
	{
		return freeObject;
	}

	virtual unsigned short getMaxObjectCount()
	{
		return maxObject;
	}

	virtual int getSizeOfObject()
	{
		return sizeof(T);
	}

	virtual void resetAllocator()
	{
		for(int i=0; i<SIZE; i++)
		{
			stack[i] = &pool[i];
		}

		stackPointer = SIZE;
		freeObject = SIZE;
		maxObject = SIZE;
	}

	StackAllocator(T* poolPointer, unsigned short s)
	{
		SIZE = s;
		stack = new T*[SIZE];
		pool = poolPointer;

		resetAllocator();


	}

	virtual ~StackAllocator(void)
	{

	}
};

